package com.feilong.commons.core.util;

import java.util.Collection;
import java.util.Map;


/**
 *将
 * <ul>
 * <li>String</li>
 * <li>boolean</li>
 * <li>number</li>
 * <li>Map<String, Object></li>
 * <li>Collection</li>
 * </ul>
 * 等类型转成json类型
 * 
 * @author <a href="mailto:venusdrogon@163.com">金鑫</a>
 * @version 1.0 2010-2-8 下午04:06:41
 * @version 1.1 2011-3-16 18:31 支持Collection
 * @since 1.0
 */
public final class JsonUtil{

	/** Don't let anyone instantiate this class. */
	private JsonUtil(){}

	// [start] json
	/**
	 * 将对象转换成json,支持深度嵌套
	 * 
	 * @param object
	 *            对象,暂时只支持
	 *            <ul>
	 *            <li>String</li>
	 *            <li>boolean</li>
	 *            <li>number</li>
	 *            <li>Map<String, Object></li>
	 *            <li>Collection</li>
	 *            </ul>
	 *            类型
	 * @return json字符串
	 */
	@SuppressWarnings("unchecked")
	public static String objectToJson(Object object){
		if (null != object){
			// 字符串
			if (object instanceof String){
				return stringToJson((String) object);
			}
			// 布尔
			if (object instanceof Boolean){
				return ((Boolean) object).toString();
			}
			// 数组
			if (object instanceof Number){
				return ((Number) object).toString();
			}
			// map
			if (object instanceof Map){
				return mapToJson((Map<String, Object>) object);
			}
			// 对象数组
			if (object instanceof Object[]){
				return arrayToJson((Object[]) object);
			}
			// 集合
			if (object instanceof Collection){
				return arrayToJson(((Collection) object).toArray());
			}
			// 不支持的对象抛出异常
			throw new RuntimeException("FeiLongJson.objectToJson(Object object)暂不支持:" + object.getClass().getName() + "类型");
		}
		return "null";
	}

	// **************************************以下为私有方法*************************************************************
	/**
	 * 将map 转换成json格式(JavaScript Object Notation) 一般用于ajax
	 * 
	 * @param map
	 *            map元素
	 * @return 转换成的json格式字符串
	 */
	private static String mapToJson(Map<String, Object> map){
		if (Validator.isNotNull(map)){
			StringBuilder sb = new StringBuilder(map.size() << 4);
			sb.append('{');
			for (Map.Entry<String, Object> entry : map.entrySet()){
				sb.append('\"');
				sb.append(entry.getKey());
				sb.append('\"');
				sb.append(':');
				sb.append(objectToJson(entry.getValue()));
				sb.append(',');
			}
			// 将最后的 ',' 变为 '}':
			sb.setCharAt(sb.length() - 1, '}');
			return sb.toString();
		}
		return "{}";
	}

	/**
	 * 数组转换成json
	 * 
	 * @param object
	 *            object数组
	 * @return
	 */
	private static String arrayToJson(Object[] object){
		if (object.length != 0){
			StringBuilder sb = new StringBuilder(object.length << 4);
			sb.append('[');
			for (Object o : object){
				sb.append(objectToJson(o));
				sb.append(',');
			}
			// 将最后添加的 ',' 变为 ']':
			sb.setCharAt(sb.length() - 1, ']');
			return sb.toString();
		}
		return "[]";
	}

	/**
	 * 字符串转换成json
	 * 
	 * @param s
	 *            字符串
	 * @return
	 */
	private static String stringToJson(String s){
		StringBuilder sb = new StringBuilder(s.length() + 20);
		sb.append('\"');
		char c;
		for (int i = 0; i < s.length(); ++i){
			c = s.charAt(i);
			switch (c) {
				case '\"':
					sb.append("\\\"");
					break;
				case '\\':
					sb.append("\\\\");
					break;
				case '/':
					sb.append("\\/");
					break;
				case '\b':
					sb.append("\\b");
					break;
				case '\f':
					sb.append("\\f");
					break;
				case '\n':
					sb.append("\\n");
					break;
				case '\r':
					sb.append("\\r");
					break;
				case '\t':
					sb.append("\\t");
					break;
				default:
					sb.append(c);
			}
		}
		sb.append('\"');
		return sb.toString();
	}
	// [end]
}